// stdx/pathx.rs
// CRITICAL: Path/PathBuf 示例，连接、显示与转换为 OsStr。
// AUTO_COMMENT: 不进行实际文件系统写入。

#[allow(dead_code)]
pub fn stdx_examples_pathx() {
    use std::ffi::OsStr;
    use std::path::{Path, PathBuf};

    // -------------------
    // 创建 Path 和 PathBuf
    // -------------------

    // 从字符串切片创建 `Path`。`Path` 是一个不可变的路径视图。
    let path = Path::new("/tmp/foo/bar.txt");
    println!("原始路径: {:?}", path);

    // 从 `Path` 创建一个可变的 `PathBuf`。`PathBuf` 拥有路径数据。
    let mut path_buf = path.to_path_buf();
    println!("从 Path 创建的 PathBuf: {:?}", path_buf);

    // 直接从字符串创建 `PathBuf`
    let mut path_buf_from_string = PathBuf::from("/home/user");
    println!("从字符串创建的 PathBuf: {:?}", path_buf_from_string);

    // -------------------
    // 路径拼接
    // -------------------

    // 使用 `push` 方法向 `PathBuf` 添加一个路径段
    path_buf_from_string.push("documents");
    path_buf_from_string.push("report.docx");
    println!("拼接后的路径: {:?}", path_buf_from_string); // 输出: "/home/user/documents/report.docx"

    // -------------------
    // 提取路径组件
    // -------------------

    // 获取父目录
    if let Some(parent) = path.parent() {
        println!("父目录: {:?}", parent); // 输出: "/tmp/foo"
    }

    // 获取文件名
    if let Some(file_name) = path.file_name() {
        println!("文件名: {:?}", file_name); // 输出: "bar.txt"
    }

    // 获取文件名（不含扩展名）
    if let Some(file_stem) = path.file_stem() {
        println!("文件名 (无扩展名): {:?}", file_stem); // 输出: "bar"
    }

    // 获取扩展名
    if let Some(ext) = path.extension() {
        println!("扩展名: {:?}", ext); // 输出: "txt"
    }

    // 判断路径是否为绝对路径
    println!("是否为绝对路径: {}", path.is_absolute());
    // 判断路径是否为相对路径
    println!("是否为相对路径: {}", path.is_relative());

    // 路径拼接与分割
    let joined = path.join("subdir").join("file.log");
    println!("拼接后的路径: {:?}", joined);
    let ancestors: Vec<_> = path.ancestors().collect();
    println!("所有祖先路径: {:?}", ancestors);

    // 转换为 OsStr
    let os_str: &OsStr = path.as_os_str();
    println!("OsStr 类型: {:?}", os_str);

    // PathBuf 转为字符串（如果可用）
    if let Some(s) = path_buf.to_str() {
        println!("PathBuf 转为字符串: {}", s);
    }

    // PathBuf 清空和追加
    path_buf_from_string.clear();
    path_buf_from_string.push("new_file.txt");
    println!("清空后追加: {:?}", path_buf_from_string);

    // -------------------
    // 路径属���检查
    // -------------------

    // 检查是否为绝对路径
    println!("路径 {:?} 是绝对路径吗? {}", path, path.is_absolute()); // true
    let relative_path = Path::new("./docs/images");
    println!(
        "路径 {:?} 是绝对路径吗? {}",
        relative_path,
        relative_path.is_absolute()
    ); // false

    // 检查路径是否存在（需要文件系统交互，这里仅作演示）
    // 注意：`exists()` 会查询文件系统，可能会失败。
    // 在这个例子中，我们不执行实际的I/O，所以只展示用法。
    // println!("路径 {:?} 存在吗? {}", path, path.exists());

    // -------------------
    // 路径修改
    // -------------------

    // 替换文件名
    let path_with_new_filename = path.with_file_name("baz.rs");
    println!("替换文件名后: {:?}", path_with_new_filename); // "/tmp/foo/baz.rs"

    // 替换扩展名
    let path_with_new_ext = path.with_extension("md");
    println!("替换扩展名后: {:?}", path_with_new_ext); // "/tmp/foo/bar.md"

    // 移除路径的最后一个组件并返回父路径
    path_buf.pop();
    println!("pop 后的 PathBuf: {:?}", path_buf); // "/tmp/foo"

    // -------------------
    // 路径与字符串转换
    // -------------------

    // 将路径转换为字符串切片 `&str`
    // 如果路径包含无效的 UTF-8 字符，`to_str()` 会返回 `None`
    if let Some(s) = path.to_str() {
        println!("转换为 &str: {}", s);
    }

    // `to_string_lossy()` 会将无效的 UTF-8 字符替换为
    // 这种转换总是成功的，返回一个 `Cow<str>`
    let lossy_str = path.to_string_lossy();
    println!("有损转换为字符串: {}", lossy_str);

    // 路径可以与 `OsStr` 相互转换
    let os_str: &OsStr = path.as_os_str();
    println!("转换为 &OsStr: {:?}", os_str);
    let path_from_os_str = Path::new(os_str);
    println!("从 &OsStr 创建路径: {:?}", path_from_os_str);
}
